package com.jxtc.enterprise.hr.service;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jxtc.enterprise.admin.vo.AdminCompanyDeliveryInfoVO;
import com.jxtc.enterprise.admin.vo.AdminCompanyImageVO;
import com.jxtc.enterprise.common.constants.MealTypeEnum;
import com.jxtc.enterprise.common.constants.PrintMethodEnum;
import com.jxtc.enterprise.common.entity.*;
import com.jxtc.enterprise.common.enums.ShowVipUserFoodEnum;
import com.jxtc.enterprise.common.mapper.UserMapper;
import com.jxtc.enterprise.hr.dto.CompanyDTO;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.CompanyMapper;
import com.jxtc.enterprise.common.mapper.DepartmentMapper;
import com.jxtc.enterprise.hr.vo.CompanyDetailVO;
import com.jxtc.enterprise.hr.vo.DepartmentVO;
import com.jxtc.enterprise.hr.vo.MealConfigVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class HrCompanyManageService {

    private final CompanyMapper companyMapper;
    private final DepartmentMapper departmentMapper;
    private final UserMapper userMapper;

    public CompanyDetailVO queryById(String id) {
        Company company = companyMapper.selectById(id);

        if (company == null) {
            log.debug("CompanyService.queryById: company not found, id = {}", id);
            throw new IllegalArgumentException("该公司不存在");
        }

        QueryWrapper<Department> wrapper = new QueryWrapper<Department>().eq("company_id", company.getId());
        List<Department> departments = departmentMapper.selectList(wrapper);

        List<DepartmentVO> departmentVOList = departments.stream()
                .map(department -> new DepartmentVO(department.getId(), department.getName(), department.getAddress()))
                .collect(Collectors.toList());

        return buildCompanyDetailVO(company, departmentVOList);
    }

    private CompanyDetailVO buildCompanyDetailVO(Company company, List<DepartmentVO> departmentVOList) {
        CompanyDetailVO vo = new CompanyDetailVO();
        vo.setId(company.getId());
        vo.setName(company.getName());
        vo.setAddress(company.getAddress());
        vo.setDepartments(departmentVOList);
        vo.setAutoRecharge(company.getAutoRecharge());
        vo.setThreshold(company.getThreshold());
        vo.setAmount(company.getAmount());
        vo.setHrName(company.getHrName());
        vo.setPhoneNumber(company.getPhoneNumber());
        vo.setPassword(company.getPassword());
        vo.setStopFlag(company.getStopFlag());

        // 是否显示客户餐
        boolean showVipUserFoodBtn = company.getShowVipUserFoodBtn().equals(ShowVipUserFoodEnum.SHOW_VIP_USER_FOOD.getValue());
        vo.setShowVipUserFoodBtn(showVipUserFoodBtn);

        String imageStr = (company.getImages() != null && !company.getImages().isEmpty()) ? company.getImages() : "{}";
        vo.setImages(JSONUtil.toBean(imageStr, AdminCompanyImageVO.class));

        String mealsConfig = (company.getMealsConfig() != null && !company.getMealsConfig().isEmpty()) ? company.getMealsConfig() : "[]";
        List<MealConfig> mealTypes = JSONObject.parseArray(mealsConfig, MealConfig.class);

        // 如果 company 表中的 meals_config 字段是默认值 "[]"，则表示该公司还没有配置默认的配送时间相关信息
        // 此时提供默认 mealTypes 信息
        if (mealTypes.isEmpty()) {
            mealTypes = getDefaultMealConfigList();
        }

        List<MealConfigVO> mealTypeVOList = mealTypes.stream()
                .map(this::buildMealConfigVO)
                .collect(Collectors.toList());
        vo.setMealTypes(mealTypeVOList);
        return vo;
    }

    /**
     * 根据 MealTypeEnum 枚举类中的信息构建默认的用餐时段信息
     */
    private List<MealConfig> getDefaultMealConfigList() {
        List<MealConfig> defaultMealConfigs = new ArrayList<>();

        for (MealTypeEnum mealTypeEnum : MealTypeEnum.values()) {
            MealConfig mealConfig = new MealConfig();
            mealConfig.setMealType(mealTypeEnum.getMealTypeEn());
            mealConfig.setStartTime(mealTypeEnum.getStartTime());
            mealConfig.setEndTime(mealTypeEnum.getEndTime());
            mealConfig.setDeliveryTime(mealTypeEnum.getDeliveryTime());
            mealConfig.setPrintTime(mealTypeEnum.getPrintTime());
            mealConfig.setPrintType(mealTypeEnum.getPrintType());
            // 默认该公司所有订餐时段都是未启用状态
            mealConfig.setEnabled(false);

            defaultMealConfigs.add(mealConfig);
        }

        return defaultMealConfigs;
    }

    /**
     * 将 company 表中的 meals_config 信息转换成前端可用的 mealTypes 信息
     */
    private MealConfigVO buildMealConfigVO(MealConfig mealConfig) {
        MealConfigVO mealConfigVO = new MealConfigVO();
        mealConfigVO.setMealType(mealConfig.getMealType());
        mealConfigVO.setEnabled(mealConfig.getEnabled());
        mealConfigVO.setStartTime(mealConfig.getStartTime());
        mealConfigVO.setEndTime(mealConfig.getEndTime());
        mealConfigVO.setDeliveryTime(mealConfig.getDeliveryTime());
        mealConfigVO.setPrintType(mealConfig.getPrintType());
        mealConfigVO.setPrintTime(mealConfig.getPrintTime());
        return mealConfigVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(CompanyDTO dto) {
        if (dto.getId() == null || dto.getId().isEmpty()) {
            throw new IllegalArgumentException("修改公司信息时，id 字段不能为空");
        }

        Company saved = companyMapper.selectById(dto.getId());
        if (saved == null) {
            throw new IllegalArgumentException("该公司不存在");
        }

        Company company = new Company();
        company.setId(dto.getId());
        company.setName(dto.getName());
        company.setAddress(dto.getAddress());
        company.setThreshold(dto.getThreshold());
        company.setAmount(dto.getAmount());
        if (dto.getHrName() != null && !dto.getHrName().isEmpty()) {
            company.setHrName(dto.getHrName());
        }
        if (dto.getPhoneNumber() != null && !dto.getPhoneNumber().isEmpty()) {
            company.setPhoneNumber(dto.getPhoneNumber());
        }
        if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
            company.setPassword(dto.getPassword());
        }
        if (dto.getAutoRecharge() != null) {
            company.setAutoRecharge(dto.getAutoRecharge());
        }

        if (dto.getShowVipUserFoodBtn() != null) {
            int showVipUserFoodBtn = dto.getShowVipUserFoodBtn() ? ShowVipUserFoodEnum.SHOW_VIP_USER_FOOD.getValue() : ShowVipUserFoodEnum.HIDE_VIP_USER_FOOD.getValue();

            if (!saved.getShowVipUserFoodBtn().equals(showVipUserFoodBtn)) {
                // 数据库中保存的是否显示客户餐与前端传递过来的值不一致的情况下，才修改该字段
                // 否则每次未修改该字段时点击保存，都会导致联动修改 user 表中的数据
                company.setShowVipUserFoodBtn(showVipUserFoodBtn);

                // 联动修改该公司下员工表的 ShowVipFoodBtn 字段
                LambdaUpdateWrapper<User> userLambdaUpdateWrapper = new LambdaUpdateWrapper<User>()
                        .eq(User::getCompanyId, dto.getId())
                        .eq(User::getDelFlag, false);
                User user = new User();
                user.setShowVipFoodBtn(showVipUserFoodBtn);
                int updateCount = userMapper.update(user, userLambdaUpdateWrapper);
                log.info("/editCompany, 联动修改该公司下员工表的 ShowVipFoodBtn 字段, updateCount: {}", updateCount);
            }
        }

        // 更新成功
        if (companyMapper.updateById(company) > 0) {
            return;
        }

        throw new ModifyFailureException("更新公司信息失败，请稍后重试");
    }
}
